﻿namespace H2.Streams.Sections
{
    using H2.Streams;
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Reflection;
    using System.Runtime.InteropServices;

    public class Bitmaps
    {
        private List<BitmapCollection> BitmapCollectionsCache;
        public static RGBA_ByteColor[] H2Palette;
        public static bool H2PaletteLoaded = false;
        private MapStream Map;
        private List<string> PathCache;

        internal Bitmaps(MapStream map)
        {
            this.Map = map;
            this.CreateCache();
        }

        private void CreateCache()
        {
            this.PathCache = new List<string>(this.Map.Tags.GetStringArrayOfClass("bitm"));
            TagInfo[] tagInfoArrayOfClass = this.Map.Tags.GetTagInfoArrayOfClass("bitm");
            this.BitmapCollectionsCache = new List<BitmapCollection>(this.PathCache.Count);
            for (int i = 0; i < this.PathCache.Count; i++)
            {
                this.BitmapCollectionsCache.Add(new BitmapCollection(this.Map, tagInfoArrayOfClass[i].Offset));
            }
        }

        public static byte[] DecodeDXT1(int width, int height, byte[] SourceData)
        {
            RGBA_IntColor[] colorArray = new RGBA_IntColor[5];
            int index = 0;
            byte[] buffer = new byte[(width * height) * 4];
            int num5 = width / 4;
            if (num5 == 0)
            {
                num5 = 1;
            }
            for (int i = 0; i < (width * height); i += 0x10)
            {
                int num2 = (SourceData[index + 1] << 8) | SourceData[index];
                int num3 = (SourceData[index + 3] << 8) | SourceData[index + 2];
                bool flag = num2 <= num3;
                colorArray[0] = ShortToRGBA(num2);
                colorArray[1] = ShortToRGBA(num3);
                if (!flag)
                {
                    colorArray[2] = GradientColors(colorArray[0], colorArray[1]);
                    colorArray[3] = GradientColors(colorArray[1], colorArray[0]);
                }
                else
                {
                    RGBA_IntColor color2 = colorArray[0];
                    colorArray[2] = GradientColorsHalf(colorArray[0], colorArray[1]);
                    colorArray[3] = color2;
                }
                int num = ((SourceData[index + 4] | (SourceData[index + 5] << 8)) | (SourceData[index + 6] << 0x10)) | (SourceData[index + 7] << 0x18);
                int num7 = i / 0x10;
                long num8 = num7 % num5;
                long num9 = (num7 - num8) / ((long) num5);
                int num11 = (height < 4) ? height : 4;
                int num12 = (width < 4) ? width : 4;
                for (int j = 0; j < num11; j++)
                {
                    for (int k = 0; k < num12; k++)
                    {
                        RGBA_IntColor rcs = colorArray[num & 3];
                        num = num >> 2;
                        long num10 = (((((num9 * 4L) + j) * width) + (num8 * 4L)) + k) * 4L;
                        RGBAToInt(rcs);
                        buffer[(int) ((IntPtr) num10)] = Convert.ToByte(rcs.B);
                        buffer[(int) ((IntPtr) (num10 + 1L))] = Convert.ToByte(rcs.G);
                        buffer[(int) ((IntPtr) (num10 + 2L))] = Convert.ToByte(rcs.R);
                        buffer[(int) ((IntPtr) (num10 + 3L))] = Convert.ToByte(rcs.A);
                    }
                }
                index += 8;
            }
            return buffer;
        }

        public static byte[] DecodeDXT23(int width, int height, byte[] SourceData)
        {
            RGBA_IntColor[] colorArray = new RGBA_IntColor[5];
            byte[] buffer = new byte[(width * height) * 4];
            int num2 = width / 4;
            if (num2 == 0)
            {
                num2 = 1;
            }
            for (int i = 0; i < (width * height); i += 0x10)
            {
                RGBA_IntColor color2 = ShortToRGBA(SourceData[i + 8] | (SourceData[i + 9] << 8));
                RGBA_IntColor color3 = ShortToRGBA(SourceData[i + 10] | (SourceData[i + 11] << 8));
                RGBA_IntColor color4 = GradientColors(colorArray[0], colorArray[1]);
                RGBA_IntColor color5 = GradientColors(colorArray[1], colorArray[0]);
                colorArray[0] = color2;
                colorArray[1] = color3;
                colorArray[2] = color4;
                colorArray[3] = color5;
                int num = ((SourceData[i + 12] | (SourceData[i + 13] << 8)) | (SourceData[i + 14] << 0x10)) | (SourceData[i + 15] << 0x18);
                int num4 = i / 0x10;
                long num5 = num4 % num2;
                long num6 = (num4 - num5) / ((long) num2);
                int num9 = (height < 4) ? height : 4;
                int num10 = (width < 4) ? width : 4;
                for (int j = 0; j < num9; j++)
                {
                    int num8 = SourceData[i + (2 * j)] | (SourceData[(i + (2 * j)) + 1] << 8);
                    for (int k = 0; k < num10; k++)
                    {
                        RGBA_IntColor color = colorArray[num & 3];
                        num = num >> 2;
                        color.A = (num8 & 15) * 0x10;
                        num8 = num8 >> 4;
                        long num7 = (((((num6 * 4L) + j) * width) + (num5 * 4L)) + k) * 4L;
                        buffer[(int) ((IntPtr) num7)] = (byte) color.B;
                        buffer[(int) ((IntPtr) (num7 + 1L))] = (byte) color.G;
                        buffer[(int) ((IntPtr) (num7 + 2L))] = (byte) color.R;
                        buffer[(int) ((IntPtr) (num7 + 3L))] = (byte) color.A;
                    }
                }
            }
            return buffer;
        }

        public static byte[] DecodeDXT45(int width, int height, byte[] SourceData)
        {
            RGBA_IntColor[] colorArray = new RGBA_IntColor[4];
            byte[] buffer = new byte[(width * height) * 4];
            int num2 = width / 4;
            if (num2 == 0)
            {
                num2 = 1;
            }
            for (int i = 0; i < (width * height); i += 0x10)
            {
                colorArray[0] = ShortToRGBA(SourceData[i + 8] | (SourceData[i + 9] << 8));
                colorArray[1] = ShortToRGBA(SourceData[i + 10] | (SourceData[i + 11] << 8));
                colorArray[2] = GradientColors(colorArray[0], colorArray[1]);
                colorArray[3] = GradientColors(colorArray[1], colorArray[0]);
                int num = ((SourceData[i + 12] | (SourceData[i + 13] << 8)) | (SourceData[i + 14] << 0x10)) | (SourceData[i + 15] << 0x18);
                byte[] buffer2 = new byte[8];
                buffer2[0] = SourceData[i];
                buffer2[1] = SourceData[i + 1];
                if (buffer2[0] > buffer2[1])
                {
                    buffer2[2] = (byte) ((((6 * buffer2[0]) + buffer2[1]) + 3) / 7);
                    buffer2[3] = (byte) ((((5 * buffer2[0]) + (2 * buffer2[1])) + 3) / 7);
                    buffer2[4] = (byte) ((((4 * buffer2[0]) + (3 * buffer2[1])) + 3) / 7);
                    buffer2[5] = (byte) ((((3 * buffer2[0]) + (4 * buffer2[1])) + 3) / 7);
                    buffer2[6] = (byte) ((((2 * buffer2[0]) + (5 * buffer2[1])) + 3) / 7);
                    buffer2[7] = (byte) (((buffer2[0] + (6 * buffer2[1])) + 3) / 7);
                }
                else
                {
                    buffer2[2] = (byte) ((((4 * buffer2[0]) + buffer2[1]) + 2) / 5);
                    buffer2[3] = (byte) ((((3 * buffer2[0]) + (2 * buffer2[1])) + 2) / 5);
                    buffer2[4] = (byte) ((((2 * buffer2[0]) + (3 * buffer2[1])) + 2) / 5);
                    buffer2[5] = (byte) (((buffer2[0] + (4 * buffer2[1])) + 2) / 5);
                    buffer2[6] = 0;
                    buffer2[7] = 0xff;
                }
                int num4 = SourceData[i + 2] | (SourceData[i + 3] << 8);
                long num5 = ((SourceData[i + 4] | (SourceData[i + 5] << 8)) | (SourceData[i + 6] << 0x10)) | (SourceData[i + 7] << 0x18);
                long num6 = num4 | (num5 << 0x10);
                int num7 = i / 0x10;
                long num8 = num7 % num2;
                long num9 = (num7 - num8) / ((long) num2);
                int num11 = (height < 4) ? height : 4;
                int num12 = (width < 4) ? width : 4;
                for (int j = 0; j < num11; j++)
                {
                    for (int k = 0; k < num12; k++)
                    {
                        RGBA_IntColor color = colorArray[num & 3];
                        num = num >> 2;
                        color.A = buffer2[(int) ((IntPtr) (num6 & 7L))];
                        num6 = num6 >> 3;
                        long num10 = (((((num9 * 4L) + j) * width) + (num8 * 4L)) + k) * 4L;
                        buffer[(int) ((IntPtr) num10)] = (byte) color.B;
                        buffer[(int) ((IntPtr) (num10 + 1L))] = (byte) color.G;
                        buffer[(int) ((IntPtr) (num10 + 2L))] = (byte) color.R;
                        buffer[(int) ((IntPtr) (num10 + 3L))] = (byte) color.A;
                    }
                }
            }
            return buffer;
        }

        private static RGBA_IntColor GradientColors(RGBA_IntColor Col1, RGBA_IntColor Col2)
        {
            RGBA_IntColor color;
            color.R = ((Col1.R * 2) + Col2.R) / 3;
            color.G = ((Col1.G * 2) + Col2.G) / 3;
            color.B = ((Col1.B * 2) + Col2.B) / 3;
            color.A = 0xff;
            return color;
        }

        private static RGBA_IntColor GradientColorsHalf(RGBA_IntColor Col1, RGBA_IntColor Col2)
        {
            RGBA_IntColor color;
            color.R = (Col1.R / 2) + (Col2.R / 2);
            color.G = (Col1.G / 2) + (Col2.G / 2);
            color.B = (Col1.B / 2) + (Col2.B / 2);
            color.A = 0xff;
            return color;
        }

        public static void LoadHalo2Palette()
        {
            byte[] buffer = new byte[] { 
                0xff, 0x7e, 0x7e, 0xff, 0xff, 0x7f, 0x7e, 0xff, 0xff, 0x80, 0x7e, 0xff, 0xff, 0x81, 0x7e, 0xff, 
                0xff, 0x7e, 0x7f, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xff, 0x80, 0x7f, 0xff, 0xff, 0x81, 0x7f, 0xff, 
                0xff, 0x7e, 0x80, 0xff, 0xff, 0x7f, 0x80, 0xff, 0xff, 0x80, 0x80, 0xff, 0xff, 0x81, 0x80, 0xff, 
                0xff, 0x7e, 0x81, 0xff, 0xff, 0x7f, 0x81, 0xff, 0xff, 0x80, 0x81, 0xff, 0xff, 0x81, 0x81, 0xff, 
                0xff, 130, 0x7f, 0xff, 0xff, 0x7f, 0x83, 0xff, 0xff, 0x7f, 0x7d, 0xff, 0xff, 0x83, 0x81, 0xff, 
                0xff, 0x7c, 0x81, 0xff, 0xff, 130, 0x7c, 0xff, 0xff, 0x81, 0x84, 0xff, 0xff, 0x7c, 0x7d, 0xff, 
                0xff, 0x85, 0x7f, 0xff, 0xff, 0x7d, 0x84, 0xff, 0xff, 0x80, 0x7a, 0xff, 0xff, 0x84, 0x84, 0xff, 
                0xff, 0x7a, 0x80, 0xff, 0xff, 0x85, 0x7c, 0xff, 0xff, 0x7f, 0x87, 0xff, 0xff, 0x7c, 0x7a, 0xff, 
                0xff, 0x88, 130, 0xff, 0xff, 0x79, 0x84, 0xff, 0xff, 0x83, 120, 0xff, 0xff, 0x84, 0x88, 0xff, 
                0xff, 0x77, 0x7c, 0xff, 0xff, 0x89, 0x7d, 0xff, 0xff, 0x7b, 0x89, 0xff, 0xff, 0x7d, 0x76, 0xff, 
                0xff, 0x89, 0x86, 0xff, 0xff, 0x75, 130, 0xff, 0xff, 0x87, 0x77, 0xff, 0xff, 0x81, 140, 0xff, 
                0xff, 0x77, 120, 0xff, 0xff, 0x8d, 0x80, 0xff, 0xff, 0x77, 0x89, 0xff, 0xff, 0x81, 0x73, 0xff, 
                0xff, 0x88, 0x8b, 0xff, 0xff, 0x72, 0x7e, 0xff, 0xff, 140, 120, 0xff, 0xff, 0x7c, 0x8e, 0xff, 
                0xff, 0x79, 0x73, 0xff, 0xff, 0x8e, 0x85, 0xff, 0xff, 0x71, 0x86, 0xff, 0xfe, 0x87, 0x71, 0xff, 
                0xfe, 0x85, 0x90, 0xff, 0xfe, 0x71, 120, 0xff, 0xfe, 0x91, 0x7c, 0xff, 0xfe, 0x76, 0x8e, 0xff, 
                0xfe, 0x7e, 110, 0xff, 0xfe, 0x8e, 140, 0xff, 0xfe, 0x6d, 0x81, 0xff, 0xfe, 0x8e, 0x72, 0xff, 
                0xfe, 0x7f, 0x93, 0xff, 0xfe, 0x73, 0x71, 0xff, 0xfe, 0x94, 0x83, 0xff, 0xfe, 0x6f, 140, 0xff, 
                0xfe, 0x85, 0x6b, 0xff, 0xfe, 0x8b, 0x93, 0xff, 0xfe, 0x6b, 0x79, 0xff, 0xfe, 0x94, 0x77, 0xff, 
                0xfd, 0x77, 0x95, 0xff, 0xfd, 120, 0x6a, 0xff, 0xfd, 0x95, 0x8b, 0xff, 0xfd, 0x69, 0x86, 0xff, 
                0xfd, 0x8d, 0x6c, 0xff, 0xfd, 0x84, 0x98, 0xff, 0xfd, 0x6c, 0x71, 0xff, 0xfd, 0x99, 0x7e, 0xff, 
                0xfd, 0x6f, 0x93, 0xff, 0xfd, 0x80, 0x66, 0xff, 0xfd, 0x92, 0x93, 0xff, 0xfd, 0x65, 0x7e, 0xff, 
                0xfd, 150, 0x6f, 0xff, 0xfc, 0x7b, 0x9b, 0xff, 0xfc, 0x71, 0x68, 0xff, 0xfc, 0x9b, 0x87, 0xff, 
                0xfc, 0x67, 0x8d, 0xff, 0xfc, 0x8a, 0x65, 0xff, 0xfc, 0x8b, 0x9b, 0xff, 0xfc, 0x65, 0x73, 0xff, 
                0xfc, 0x9d, 0x77, 0xff, 0xfc, 0x71, 0x9b, 0xff, 0xfc, 0x79, 0x62, 0xff, 0xfc, 0x9a, 0x92, 0xff, 
                0xfb, 0x60, 0x84, 0xff, 0xfb, 0x95, 0x67, 0xff, 0xfb, 0x81, 0xa1, 0xff, 0xfb, 0x69, 0x69, 0xff, 
                0xfb, 0xa1, 0x81, 0xff, 0xfb, 0x66, 150, 0xff, 0xfb, 0x84, 0x5e, 0xff, 0xfb, 0x94, 0x9c, 0xff, 
                0xfb, 0x5e, 120, 0xff, 0xfb, 0x9f, 110, 0xff, 250, 0x75, 0xa2, 0xff, 250, 0x71, 0x5f, 0xff, 
                250, 0xa2, 0x8e, 0xff, 250, 0x5d, 0x8d, 0xff, 250, 0x91, 0x5f, 0xff, 250, 0x8a, 0xa4, 0xff, 
                250, 0x60, 0x6c, 0xff, 250, 0xa6, 0x79, 0xff, 0xf9, 0x68, 0x9f, 0xff, 0xf9, 0x7d, 0x59, 0xff, 
                0xf9, 0x9d, 0x9b, 0xff, 0xf9, 0x58, 0x80, 0xff, 0xf9, 0x9e, 0x65, 0xff, 0xf9, 0x7c, 0xa9, 0xff, 
                0xf9, 0x67, 0x5f, 0xff, 0xf8, 0xa9, 0x87, 0xff, 0xf8, 0x5c, 0x97, 0xff, 0xf8, 0x8b, 0x57, 0xff, 
                0xf8, 0x94, 0xa6, 0xff, 0xf8, 0x57, 0x71, 0xff, 0xf8, 0xa8, 0x6f, 0xff, 0xf8, 0x6d, 0xa8, 0xff, 
                0xf7, 0x73, 0x56, 0xff, 0xf7, 0xa7, 150, 0xff, 0xf7, 0x54, 0x8a, 0xff, 0xf7, 0x9a, 0x5b, 0xff, 
                0xf7, 0x86, 0xae, 0xff, 0xf7, 0x5c, 0x62, 0xff, 0xf7, 0xaf, 0x7e, 0xff, 0xf6, 0x5e, 0xa2, 0xff, 
                0xf6, 130, 80, 0xff, 0xf6, 0x9f, 0xa5, 0xff, 0xf6, 80, 0x7a, 0xff, 0xf6, 0xa8, 100, 0xff, 
                0xf6, 0x75, 0xb0, 0xff, 0xf5, 0x67, 0x55, 0xff, 0xf5, 0xb0, 0x8f, 0xff, 0xf5, 0x52, 0x95, 0xff, 
                0xf5, 0x94, 0x51, 0xff, 0xf5, 0x92, 0xb0, 0xff, 0xf4, 0x52, 0x68, 0xff, 0xf4, 0xb2, 0x72, 0xff, 
                0xf4, 100, 0xac, 0xff, 0xf4, 0x77, 0x4c, 0xff, 0xf4, 170, 0xa1, 0xff, 0xf4, 0x4a, 0x85, 0xff, 
                0xf3, 0xa5, 0x58, 0xff, 0xf3, 0x80, 0xb7, 0xff, 0xf3, 0x5b, 0x57, 0xff, 0xf3, 0xb7, 0x85, 0xff, 
                0xf3, 0x54, 0xa2, 0xff, 0xf2, 0x8a, 0x49, 0xff, 0xf2, 0x9e, 0xb0, 0xff, 0xf2, 0x49, 0x71, 0xff, 
                0xf2, 0xb3, 0x65, 0xff, 0xf2, 0x6c, 0xb6, 0xff, 0xf1, 0x6a, 0x4a, 0xff, 0xf1, 0xb5, 0x99, 0xff, 
                0xf1, 0x48, 0x92, 0xff, 0xf1, 0x9e, 0x4c, 0xff, 240, 0x8d, 0xbb, 0xff, 240, 0x4f, 0x5d, 0xff, 
                240, 0xbc, 120, 0xff, 240, 0x59, 0xaf, 0xff, 240, 0x7d, 0x42, 0xff, 0xef, 0xac, 0xac, 0xff, 
                0xef, 0x42, 0x7d, 0xff, 0xef, 0xb0, 0x58, 0xff, 0xef, 120, 0xbf, 0xff, 0xee, 0x5c, 0x4c, 0xff, 
                0xee, 0xbf, 0x8e, 0xff, 0xee, 0x48, 160, 0xff, 0xee, 0x94, 0x42, 0xff, 0xed, 0x9c, 0xbb, 0xff, 
                0xed, 0x43, 0x67, 0xff, 0xed, 190, 0x69, 0xff, 0xed, 0x61, 0xbb, 0xff, 0xed, 0x6f, 0x3f, 0xff, 
                0xec, 0xb9, 0xa4, 0xff, 0xec, 0x3d, 140, 0xff, 0xec, 170, 0x4a, 0xff, 0xeb, 0x86, 0xc4, 0xff, 
                0xeb, 0x4d, 0x51, 0xff, 0xeb, 0xc5, 0x80, 0xff, 0xeb, 0x4d, 0xaf, 0xff, 0xea, 0x86, 0x3a, 0xff, 
                0xea, 0xab, 0xb8, 0xff, 0xea, 0x3a, 0x74, 0xff, 0xea, 0xbc, 90, 0xff, 0xe9, 0x6d, 0xc5, 0xff, 
                0xe9, 0x5f, 0x40, 0xff, 0xe9, 0xc4, 0x99, 0xff, 0xe9, 0x3d, 0x9c, 0xff, 0xe8, 0x9f, 0x3e, 0xff, 
                0xe8, 150, 0xc6, 0xff, 0xe8, 0x40, 0x5b, 0xff, 0xe7, 0xc9, 0x70, 0xff, 0xe7, 0x55, 0xbd, 0xff, 
                0xe7, 0x76, 0x35, 0xff, 0xe7, 0xba, 0xb1, 0xff, 230, 0x34, 0x83, 0xff, 230, 0xb6, 0x4a, 0xff, 
                230, 0x7d, 0xcd, 0xff, 0xe5, 0x4e, 0x45, 0xff, 0xe5, 0xcd, 0x8a, 0xff, 0xe5, 0x40, 0xad, 0xff, 
                0xe4, 0x91, 0x33, 0xff, 0xe4, 0xa7, 0xc4, 0xff, 0xe4, 0x34, 0x68, 0xff, 0xe3, 200, 0x5e, 0xff, 
                0xe3, 0x61, 0xca, 0xff, 0xe3, 0x65, 0x34, 0xff, 0xe3, 200, 0xa5, 0xff, 0xe2, 0x31, 0x95, 0xff, 
                0xe2, 0xac, 0x3b, 0xff, 0xe2, 0x8e, 0xd1, 0xff, 0xe1, 0x3f, 0x4e, 0xff, 0xe1, 0xd3, 0x79, 0xff, 
                0xe1, 0x48, 0xbd, 0xff, 0xe0, 0x80, 0x2c, 0xff, 0xe0, 0xb9, 190, 0xff, 0xe0, 0x2c, 0x79, 0xff, 
                0xdf, 0xc3, 0x4c, 0xff, 0xdf, 0x71, 0xd4, 0xff, 0xdf, 0x52, 0x38, 0xff, 0xde, 0xd3, 150, 0xff, 
                0xde, 0x33, 0xa8, 0xff, 0xdd, 0x9e, 0x2f, 0xff, 0xdd, 0xa1, 0xd1, 0xff, 0xdd, 0x31, 0x5b, 0xff, 
                220, 0xd4, 0x66, 0xff, 220, 0x54, 0xcc, 0xff, 220, 0x6d, 0x29, 0xff, 0xdb, 0xc9, 0xb3, 0xff, 
                0xdb, 0x27, 140, 0xff, 0xdb, 0xba, 0x3b, 0xff, 0xda, 0x84, 0xda, 0xff, 0xda, 0x40, 0x40, 0xff, 
                0xd9, 0xdb, 0x84, 0xff, 0xd9, 0x3a, 0xbb, 0xff, 0xd9, 140, 0x25, 0xff, 0xd8, 0xb5, 0xcb, 0xff, 
                0xd8, 0x26, 0x6c, 0xff, 0xd8, 0xd0, 0x52, 0xff, 0xd7, 100, 0xd9, 0xff, 0xd7, 0x59, 0x2b, 0xff, 
                0xd6, 0xd7, 0xa4, 0xff, 0xd6, 0x27, 160, 0xff, 0xd6, 0xac, 0x2c, 0xff, 0xff, 0x80, 0x80, 0
             };
            H2Palette = new RGBA_ByteColor[0x100];
            for (int i = 0; i < 0x100; i++)
            {
                int index = i * 4;
                H2Palette[i].R = buffer[index];
                H2Palette[i].G = buffer[index + 1];
                H2Palette[i].B = buffer[index + 2];
                H2Palette[i].A = buffer[index + 3];
            }
            H2PaletteLoaded = true;
        }

        public Bitmap LoadPreviewImage(string Path, int Chunk, ResourceStream MainMenu, ResourceStream Shared, ResourceStream SpShared)
        {
            int index = this.PathCache.IndexOf(Path);
            if (index != -1)
            {
                return this.BitmapCollectionsCache[index][Chunk].LoadPreview(MainMenu, Shared, SpShared);
            }
            return null;
        }

        private static int RGBAToInt(RGBA_IntColor rcs)
        {
            return ((((rcs.A << 0x18) | (rcs.R << 0x10)) | (rcs.G << 8)) | rcs.B);
        }

        private static RGBA_IntColor ShortToRGBA(int color)
        {
            RGBA_IntColor color2;
            color = Convert.ToUInt16(color);
            color2.R = (((color >> 11) & 0x1f) * 0xff) / 0x1f;
            color2.G = (((color >> 5) & 0x3f) * 0xff) / 0x3f;
            color2.B = ((color & 0x1f) * 0xff) / 0x1f;
            color2.A = 0xff;
            return color2;
        }

        private static int Swizzle(int x, int y, int z, MaskSet masks)
        {
            return ((SwizzleAxis(x, masks.x) | SwizzleAxis(y, masks.y)) | ((z == -1) ? 0 : SwizzleAxis(z, masks.z)));
        }

        public static byte[] Swizzle(byte[] raw, int width, int height, int depth, int bitCount, bool deswizzle)
        {
            return Swizzle(raw, 0, width, height, depth, bitCount, deswizzle);
        }

        public static byte[] Swizzle(byte[] raw, int pixOffset, int width, int height, int depth, int bitCount, bool deswizzle)
        {
            bitCount /= 8;
            int num = 0;
            int num2 = 0;
            byte[] buffer = new byte[raw.Length];
            MaskSet masks = new MaskSet(width, height, depth);
            pixOffset = 0;
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    if (deswizzle)
                    {
                        num = ((i * width) + j) * bitCount;
                        num2 = Swizzle(j, i, -1, masks) * bitCount;
                    }
                    else
                    {
                        num2 = ((i * width) + j) * bitCount;
                        num = Swizzle(j, i, -1, masks) * bitCount;
                    }
                    if ((num >= buffer.Length) || (num2 >= raw.Length))
                    {
                        return null;
                    }
                    for (int k = pixOffset; k < (bitCount + pixOffset); k++)
                    {
                        buffer[num + k] = raw[num2 + k];
                    }
                }
            }
            return buffer;
        }

        private static int SwizzleAxis(int val, int mask)
        {
            int num = 1;
            int num2 = 0;
            while (num <= mask)
            {
                if ((mask & num) != 0)
                {
                    num2 |= val & num;
                }
                else
                {
                    val = val << 1;
                }
                num = num << 1;
            }
            return num2;
        }

        public BitmapCollection this[string Path]
        {
            get
            {
                return this.BitmapCollectionsCache[this.PathCache.IndexOf(Path)];
            }
            set
            {
                this.BitmapCollectionsCache[this.PathCache.IndexOf(Path)] = value;
            }
        }

        private class MaskSet
        {
            public int x;
            public int y;
            public int z;

            public MaskSet(int w, int h, int d)
            {
                int num = 1;
                int num2 = 1;
                while (((num < w) || (num < h)) || (num < d))
                {
                    if (num < w)
                    {
                        this.x |= num2;
                        num2 = num2 << 1;
                    }
                    if (num < h)
                    {
                        this.y |= num2;
                        num2 = num2 << 1;
                    }
                    if (num < d)
                    {
                        this.z |= num2;
                        num2 = num2 << 1;
                    }
                    num = num << 1;
                }
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RGBA_ByteColor
        {
            public byte R;
            public byte G;
            public byte B;
            public byte A;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct RGBA_IntColor
        {
            public int R;
            public int G;
            public int B;
            public int A;
        }
    }
}

